package com.example.demoback.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demoback.common.Result;
import com.example.demoback.entity.Files;
import com.example.demoback.mapper.File1Mapper;
import com.example.demoback.mapper.FileMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;

import com.example.demoback.service.IFileService;
import com.example.demoback.entity.File1;
import com.example.demoback.service.IFile1Service;

import org.springframework.web.multipart.MultipartFile;


import org.springframework.web.bind.annotation.RestController;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author yyd
 * @since 2022-07-01
 */
@RestController
@RequestMapping("/file")
public class FileController {

    //引入Service
    @Resource
    private IFileService fileService;

    @Resource
    private IFile1Service file1Service;




//    //新增或更新
//    @PostMapping("/save")
//    public Result save(@RequestBody Files file) {
//
//        Boolean flag = false;
//        //判断数据是否重复
//        int a ;
//        a = getInfo(file.getMd5());
//        if (a == 1){
//            flag = fileService.saveOrUpdate(file);
//            if (flag){
//                File1 file1 =new File1();
//                BeanUtil.copyProperties(file,file1,true);
//                if (!file1Service.saveOrUpdate(file1)){
//                return Result.error1(false);
//                }
//            }
//        }else{
//            return Result.error("存在重复数据");
//        }
//        return Result.success(flag);
//    }
//
//    //根据id删除
//    @DeleteMapping("/delete/{id}")  //通过“/user/”+id 的url调用接口
//    public Result delete(@PathVariable Integer id) {
//        Boolean flag = false;
//        flag = fileService.removeById(id);
//        if (flag){
//            if (!file1Service.removeById(id)){
//                return Result.error1(false);
//            }
//        }
//        return Result.success(flag,"数据删除成功");
//    }
//    //批量删除
//    @PostMapping("/delete/batch")
//    public Boolean deleteBatch(@RequestBody List<Integer> ids){
//        return fileService.removeByIds(ids);
//    }
//
//    //查询所有
//    @GetMapping("/select/all")
//    public Result findAll() {
//        List<Files> files = fileService.list();
//        return Result.success(files);
//    }
//
//    //根据id查询
//    @GetMapping("select/{id}")
//    public Result findOne(@PathVariable Integer id) {
//        Files file = fileService.getById(id);
//        return Result.success(file);
//    }
//
//    //分页查询
//    @GetMapping("/select/page")
//    public Result findPage(@RequestParam Integer pageNum,
//                                    @RequestParam Integer pageSize,
//                                    @RequestParam(defaultValue = "") String name,//defaultValue = ""设置默认值为空
//                                    @RequestParam(defaultValue = "") String type) {
//
//        Page<Files> page = new Page<>(pageNum,pageSize);
//        QueryWrapper<Files> querWrapper = new QueryWrapper<Files>();
//        if (!"".equals(name)){
//        querWrapper.like("name",name);//默认用and连接
//        }
//        if (!"".equals(type)){
//        querWrapper.like("type",type);//或连接为querWrapper.or().like
//        }
//        IPage<Files> fileIPage = fileService.page(page,querWrapper);
//        return Result.success(fileIPage);
//    }
//
//    //导出excel表格
//    @GetMapping("/export")
//    public void export(HttpServletResponse response) throws Exception{
//        //从数据库查出所以数据
//        List<Files> list = fileService.list();
//
//        // 通过工具类创建writer 写出到磁盘路径
////        ExcelWriter writer = ExcelUtil.getWriter(filesUploadPath + "/用户信息.xlsx");
//        // 在内存操作，写出到浏览器
//        ExcelWriter writer = ExcelUtil.getWriter(true);//也可写为磁盘路径
//
//        //自定义标题别名
//        writer.addHeaderAlias("id", "文件id");
//        writer.addHeaderAlias("name", "文件名");
//        writer.addHeaderAlias("type", "文件类型");
//        writer.addHeaderAlias("size", "大小");
//        writer.addHeaderAlias("url", "下载路径");
//        writer.addHeaderAlias("isDelete", "是否删除");
//        writer.addHeaderAlias("enable", "是否禁用");
//        writer.addHeaderAlias("md5", "唯一标识");
//
//
//        // 一次性写出list内的对象到excel，使用默认样式，强制输出标题
//        writer.write(list, true);
//
//        // 设置浏览器响应的格式
//        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
//        String fileName = URLEncoder.encode("文件表", "UTF-8");
//        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
//
//        ServletOutputStream out = response.getOutputStream();//将数据刷新到输出流里面
//        writer.flush(out, true);
//        out.close();
//        writer.close();
//        }
//
//
//    public int getInfo(String key) {  //查询出一条数据
//        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("md5", key);
//        int a = 2;
//        Files one = new Files();
//        try {
//        one = fileService.getOne(queryWrapper); // 从数据库查询信息
//        } catch (Exception e) {
//        a = 3;
//        }
//        if (one == null){
//        a = 1;
//        }
//        return a; //1为不存在数据
//        //2为存在一条数据
//        //3为存在多条数据
//        }
//
//    //备用数据库查询
//    public int getInfo1(String key) {  //查询出一条数据
//        QueryWrapper<File1> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("md5", key);
//        int a = 2;
//        File1 one = new File1();
//        try {
//        one = file1Service.getOne(queryWrapper); // 从数据库查询信息
//        } catch (Exception e) {
//        a = 3;
//        }
//        if (one == null){
//        a = 1;
//        }
//        return a; //1为不存在数据
//        //2为存在一条数据
//        //3为存在多条数据
//        }


    @Value("${files.upload.path}") //取得application.yml内的磁盘路径
    private String fileUploadPath;

    @Resource
    private FileMapper fileMapper;

    @Resource
    private File1Mapper file1Mapper;

    //文件上传接口
    @PostMapping("/upload")
    public String upload(@RequestParam MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename();//获取文件名称name
        String type = FileUtil.extName(originalFilename);//获取文件类型type
        long size = file.getSize();//获取文件大小size
        //下载链接自己设url
        //默认0为未删除 is_delete 是否删除
        //默认1为可用链接 enable 是否禁用

        // 定义一个文件唯一的标识码
        String fileUUID = IdUtil.fastSimpleUUID() + StrUtil.DOT + type;

        //存储到磁盘
        File uploadFile = new File(fileUploadPath + fileUUID);//将文件读入到File对象，非Files实例
        // 判断配置的文件目录是否存在，若不存在则创建一个新的文件目录
        File parentFile = uploadFile.getParentFile();
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }

        String url;
        // 获取文件的md5
        String md5 = SecureUtil.md5(file.getInputStream());
        // 从数据库查询是否存在相同的记录
        Files dbFiles = getFileByMd5(md5);
        if (dbFiles != null) {
            url = dbFiles.getUrl();
        } else {
            // 上传文件到磁盘
            file.transferTo(uploadFile);
            // 数据库若不存在重复文件，则不删除刚才上传的文件
            url = "http://" +
//                    serverIp +
                    "localhost:9090/file/" + fileUUID;

            // 存储数据库
            Files saveFile = new Files();

            File1 file1 = new File1();

            saveFile.setName(originalFilename);
            saveFile.setType(type);
            saveFile.setSize(size/1024); // 单位 kb
            saveFile.setUrl(url);
            saveFile.setMd5(md5);
            int flag ;
            flag = fileMapper.insert(saveFile);
            BeanUtil.copyProperties(saveFile,file1,true);
            if (flag == 1){
                file1Mapper.insert(file1);
            }
        }



        // 从redis取出数据，操作完，再设置（不用查询数据库）
//        String json = stringRedisTemplate.opsForValue().get(Constants.FILES_KEY);
//        List<Files> files1 = JSONUtil.toBean(json, new TypeReference<List<Files>>() {
//        }, true);
//        files1.add(saveFile);
//        setCache(Constants.FILES_KEY, JSONUtil.toJsonStr(files1));


        // 从数据库查出数据
//        List<Files> files = fileMapper.selectList(null);
//        // 设置最新的缓存
//        setCache(Constants.FILES_KEY, JSONUtil.toJsonStr(files));

        // 最简单的方式：直接清空缓存
//        flushRedis(Constants.FILES_KEY);


        return url;

    }

    /**
     * 文件下载接口   http://localhost:9090/file/{fileUUID}
     * @param fileUUID
     * @param response
     * @throws IOException
     */
    @GetMapping("/{fileUUID}")
    public void download(@PathVariable String fileUUID, HttpServletResponse response) throws IOException {
        // 根据文件的唯一标识码获取文件
        File uploadFile = new File(fileUploadPath + fileUUID);
        // 设置输出流的格式
        ServletOutputStream os = response.getOutputStream();
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileUUID, "UTF-8"));
        response.setContentType("application/octet-stream");

        // 读取文件的字节流
        os.write(FileUtil.readBytes(uploadFile));
        os.flush();
        os.close();
    }


    /**
     * 通过文件的md5查询文件
     * @param md5
     * @return
     */
    private Files getFileByMd5(String md5) {
        // 查询文件的md5是否存在
        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("md5", md5);
        List<Files> filesList = fileMapper.selectList(queryWrapper);
        return filesList.size() == 0 ? null : filesList.get(0);
    }


    /**
     * 分页查询接口
     * @param pageNum
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public Result findPage(@RequestParam Integer pageNum,
                           @RequestParam Integer pageSize,
                           @RequestParam(defaultValue = "") String name) {

        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
        // 查询未删除的记录
        queryWrapper.eq("is_delete", false);
        queryWrapper.orderByDesc("id");
        if (!"".equals(name)) {
            queryWrapper.like("name", name);
        }
        return Result.success(fileMapper.selectPage(new Page<>(pageNum, pageSize), queryWrapper));
    }

    //通过id查询数据
    @GetMapping("/detail/{id}")
    public Result getById(@PathVariable Integer id) {
        return Result.success(fileMapper.selectById(id));
    }

    //修改标志为删除
    @DeleteMapping("/delete/{id}")
    public Result delete(@PathVariable Integer id) {
        Files files = fileMapper.selectById(id);
        File1 file1 = new File1();
        files.setIsDelete(true);
        int flag =  fileMapper.deleteById(id);
        BeanUtil.copyProperties(files,file1,true);
        if (flag == 1){
            file1Mapper.deleteById(id);
        }
//        flushRedis(Constants.FILES_KEY);
        return Result.success(flag,"已标志为删除");
    }

    //    @CachePut(value = "files", key = "'frontAll'")
    @PostMapping("/update")
    public Result update(@RequestBody Files files) {
        int flag ;
        flag = fileMapper.updateById(files);
//        flushRedis(Constants.FILES_KEY);
        File1 file1 =new File1();
        if (flag == 1){
            BeanUtil.copyProperties(files,file1,true);
            file1Mapper.updateById(file1);
        }

        return Result.success();
    }


    //批量删除
    @PostMapping("/del/batch")
    public Result deleteBatch(@RequestBody List<Integer> ids) {
        // select * from sys_file where id in (id,id,id...)
        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", ids);
        List<Files> files = fileMapper.selectList(queryWrapper);
        for (Files file : files) {
            file.setIsDelete(true);
            fileMapper.updateById(file);
        }
        return Result.success();
    }




    // 设置缓存
//    private void setCache(String key, String value) {
//        stringRedisTemplate.opsForValue().set(key, value);
//    }

    // 删除缓存
//    private void flushRedis(String key) {
//        stringRedisTemplate.delete(key);
//    }

}

